﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Messaging;

namespace CRM.Common
{
    public class QueueCommonHelper
    {
        private string Path = string.Empty;

        public QueueCommonHelper(string queuePath)
        {
            try
            {
                if (!MessageQueue.Exists(queuePath))
                {
                    MessageQueue.Create(queuePath, false)
                                .SetPermissions("Everyone", MessageQueueAccessRights.FullControl);
                }

                Path = queuePath;
            }

            catch (MessageQueueException e)
            {
                LogHelper.WriteLog(e.InnerException.Message, e);
            }
        }

        #region 连接消息队列并发送消息到队列
        /// <summary>
        /// 连接消息队列并发送消息到队列
        /// 远程模式：MessageQueue rmQ = new MessageQueue("FormatName:Direct=OS:machinename//private$//queue");
        /// rmQ.Send("sent to regular queue - Atul");对于外网的MSMQ只能发不能收
        /// </summary>
        public bool SendMessage(object message, dynamic msmqFormat)
        {
            try
            {
                //连接到本地队列
                MessageQueue myQueue = new MessageQueue(Path);

                //MessageQueue myQueue = new MessageQueue("FormatName:Direct=TCP:192.168.12.79//Private$//myQueue1");
                //MessageQueue rmQ = new MessageQueue("FormatName:Direct=TCP:121.0.0.1//private$//queue");--远程格式

                Message myMessage = new Message();

                myMessage.Body = message;

                myMessage.Priority = MessagePriority.Normal;

                myQueue.MessageReadPropertyFilter.Priority = true;

                myMessage.Formatter = new XmlMessageFormatter(new Type[] { msmqFormat });

                //发生消息到队列中
                myQueue.Send(myMessage);

                return true;
            }
            catch (ArgumentException e)
            {
                LogHelper.WriteLog(e.InnerException.Message, e);

                return false;
            }
        }
        #endregion

        #region 传递单独的给消息队列
        /// <summary>
        /// 传递单独的给消息队列
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public void SendMessage(Message message)
        {
            //连接到本地队列
            MessageQueue myQueue = new MessageQueue(Path);

            myQueue.Send(message);
        }
        #endregion

        #region 从队列获取消息并移除
        /// <summary>
        ///从队列获取消息并移除
        /// </summary>
        public object ReceiveMessage(out Message message)
        {
            Message myMessage = null;

            try
            {

                MessageQueue myQueue = new MessageQueue(Path);

                myQueue.MessageReadPropertyFilter.Priority = true;

                myMessage = myQueue.Receive();

                myMessage.Formatter = new XmlMessageFormatter(new Type[] { typeof(List<string>) });

                List<string> context = myMessage.Body as List<string>;

                message = myMessage;

                return context;
            }
            catch (MessageQueueException e)
            {
                LogHelper.WriteLog(e.InnerException.Message, e);

                message = null;

                return string.Empty;
            }
            catch (InvalidCastException e)
            {
                LogHelper.WriteLog(e.InnerException.Message, e);

                message = null;

                return string.Empty;
            }
        }
        #endregion

        #region 获取Message实体
        /// <summary>
        /// 获取Message实体
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public Message GetMessage(object message, MessagePriority level, dynamic msmqType)
        {
            Message myMessage = new Message();

            myMessage.Body = message;

            //设置等级
            myMessage.Priority = level;

            myMessage.Formatter = new XmlMessageFormatter(new Type[] { msmqType });

            return myMessage;
        }
        #endregion

        #region 清空指定队列的消息
        /// <summary>
        /// 清空指定队列的消息
        /// </summary>
        public bool ClearMessage()
        {
            try
            {
                MessageQueue myQueue = new MessageQueue(Path);

                myQueue.Purge();

                return true;
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(e.InnerException.Message, e);

                return false;
            }
        }
        #endregion

        #region 连接队列并获取队列的全部消息
        /// <summary>
        /// 连接队列并获取队列的全部消息
        /// </summary>
        public List<string> GetAllMessage()
        {

            List<string> messageList = new List<string>();

            MessageQueue myQueue = new MessageQueue(Path);

            Message[] allMessage = myQueue.GetAllMessages();

            foreach (var single in allMessage)
            {
                messageList.Add(Convert.ToString(single.Body));
            }

            return messageList;
        }
        #endregion
    }
}